package model.compresion.PPMC;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

import model.archivo.ArchivoDiccionario;
import model.compresion.TablaProbabilidades;
import model.compresion.artmetico.*;
import model.extras.bitArray.*;
import model.registro.*;

public class CompresorPPMC {

	private int orden;

	private String contextoGlobal;
	
	private boolean EOF = false; 

	private int modeloActual;

	private String contextoActual;

	private int modeloGlobal;

	//private ArrayList<RegistroPosicionFrecuencia> listaCeros = new ArrayList<RegistroPosicionFrecuencia>();

	//private ArrayList<RegistroSimbolos> listaModeloMenos1 = new ArrayList<RegistroSimbolos>(65538);

	CompresorAritmetico compresArit;

	DescompresorAritmetico descArit;

	private ArchivoDiccionario archivoModelo;

	private ArrayList<Integer> simbolosExcluidos = new ArrayList<Integer>();

	private ArrayList<ContextoPPMC> listaContextoPPMC = new ArrayList<ContextoPPMC>();

	//private static final byte[] ESC = codificador.toBytes((short) 65535);
	private static final int ESC = 65536;

	//private static final int EOF = 65537;

	private int tam1;

	private int tam2;

	private int tam3;

	private int tam4;

	//el constructor crea los archivos de los modelos 
	public CompresorPPMC(int NewOrden) throws Exception {
		this.orden = NewOrden;
		this.contextoGlobal = null;
		this.modeloGlobal = 0;
		tam1 = tam2 = tam3 = tam4 = 0;

		compresArit = new CompresorAritmetico();
		//generarListaDeUnos(listaModeloMenos1);
		//generarListaDeCeros(listaCeros);

		crearArchivos(this.orden);
	}

	//debo modificar el ctx actual
	public void ComprimirPPMC(Integer simboloAComprimir) throws Exception {

		String simbolo = new String(simboloAComprimir.toString());

		int comprimido = 0; //0 = false

		
		modeloActual = modeloGlobal;

		contextoActual = contextoGlobal;
		//System.out.println();
		//System.out.println("se comprime: " + simbolo);

		do {
			//System.out.println();

			if (modeloActual != -1) {
				boolean ctxEncontrado = false;
				this.archivoModelo = abrirArchivoModeloActual(this.modeloActual);
				archivoModelo.rwArchivo();

				// cargo la lista de contextos que esta en el archivo segun el modelo
				cargarListaContextosModeloActual();

				// recorro la lista de contextos al menos que este vacia y el
				// modelo sea mayor a 0
				if (!this.listaContextoPPMC.isEmpty() && (modeloActual > 0)) {
					for (ContextoPPMC contextoAux : listaContextoPPMC) {
						// los modelos -1 y 0 tienen contextos nulos
						if (contextoAux.getContexto().equals(contextoActual)) {
							// encotre el contexto, ahora busco el simbolo
							comprimido = comprimirEnContexto(contextoAux,
									simboloAComprimir);
							ctxEncontrado = true;
							break;
						}
					}// End for listaContexto
					if (ctxEncontrado == false) { // no encontre el contexto
						agregoContextoAlModelo(contextoActual,
								simboloAComprimir);
						
					}

				} // fin lista ctx vacia o modelo > 0
				else {
					if (modeloActual == 0) { // no tiene contextos, solamente
						// revisa los simbolos
						ContextoPPMC contextoAux = listaContextoPPMC.get(0);
						comprimido = comprimirEnContexto(contextoAux,
								simboloAComprimir);
					} else {
						agregoContextoAlModelo(contextoActual,
								simboloAComprimir);
						
					}
				}

				cierroArhivo(archivoModelo, modeloActual);

		//		this.archivoModelo.cerrarArchivo();

				this.modeloActual--;

				if (modeloActual > 0) {
					disminuyoContexto(contextoActual, modeloGlobal- modeloActual);
					
				}
			}

			if ((modeloActual == -1) && (comprimido == 0)) {
				emitoUltimoNivel(simboloAComprimir);
			}

		} while ((modeloActual >= 0) && (comprimido == 0));

		if (modeloGlobal < orden) {
			modeloGlobal++;
			aumentoContexto(simbolo);
		} else
			corroContexto(simbolo);

		modificarTamanio(modeloGlobal, simbolo.length());

	}

	public byte[] DescomprimirPPMC(BitArrayStream stream) throws Exception {

		this.tam1 = this.tam2 = this.tam3 = this.tam4 =0;
		
		crearArchivos(this.orden);
		this.modeloGlobal = 0;
		this.contextoGlobal = null;
		//BitArrayStream carADes = new BitArrayStream();
		descArit = new DescompresorAritmetico(stream);
        //System.out.println();
        //System.out.println();
		

		do {
			boolean comprimido = false;
			modeloActual = modeloGlobal;
			contextoActual = contextoGlobal;

			do {
						
			if (modeloActual != -1) {
				boolean ctxEncontrado = false;
				this.archivoModelo = abrirArchivoModeloActual(this.modeloActual);
				archivoModelo.rwArchivo();

				// cargo la lista de contextos que esta en el archivo segun el modelo
				cargarListaContextosModeloActual();

				if (!this.listaContextoPPMC.isEmpty() && (modeloActual > 0)) {
					for (ContextoPPMC contextoAux : listaContextoPPMC) {
						// los modelos -1 y 0 tienen contextos nulos
						if (contextoAux.getContexto().equals(contextoActual)) {
							
						/*	System.out.println();
							System.out.println();
							System.out.println("llamo al aritmetico");
							System.out.println("Modelo: "+modeloActual+"\tContexto: "+contextoActual);
						*/	
							EOF = descomprimirEnContexto(contextoAux, contextoAux.getArrayPosFrecuencia());
							
							ctxEncontrado = true;
							break;
						}
					}// End for listaContexto
					if (ctxEncontrado == false) { // no encontre el contexto
						/*
						System.out.println();
						System.out.println();
						System.out.println("llamo al aritmetico");
						System.out.println("Modelo: "+modeloActual+"\tContexto: "+contextoActual);
						*/
						EOF = descompresorAgregoContextoAlModelo(contextoActual);
						
					}

				} // fin lista ctx vacia o modelo > 0
				else {
					if (modeloActual == 0) {
						ContextoPPMC contextoAux = listaContextoPPMC.get(0);
						/*
						System.out.println();
						System.out.println();
						System.out.println("llamo al aritmetico");
						System.out.println("Modelo: "+modeloActual+"\tContexto: "+contextoActual);
						*/
						EOF = descomprimirEnContexto(contextoAux,contextoAux.getArrayPosFrecuencia());
						
					} else {
						/*
						System.out.println();
						System.out.println();
						System.out.println("llamo al aritmetico");
						System.out.println("Modelo: "+modeloActual+"\tContexto: "+contextoActual);
						*/
						EOF = descompresorAgregoContextoAlModelo(contextoActual);
						
					}
				}

				cierroArhivo(archivoModelo, modeloActual);

				//this.archivoModelo.cerrarArchivo();
				this.modeloActual--;

				if (modeloActual > 0) 
					disminuyoContexto(contextoActual, modeloGlobal- modeloActual);
				
				if (descArit.getUltimoDescomprimido() != ESC){
					comprimido = true;
					
				}
			}

			if ((modeloActual == -1) && (comprimido == false)&&(EOF==false)) {
				
			/*	System.out.println();
				System.out.println();
				System.out.println("llamo al aritmetico");
				System.out.println("Modelo: "+modeloActual+"\tContexto: "+contextoActual);
			*/	
				EOF = descomprimoUltimoNivel();
				comprimido = true;
			}
			
		}while ((comprimido == false)&&(EOF==false));
			
		Integer simboloComprimido = descArit.getUltimoDescomprimido();

		String simbolo = new String(simboloComprimido.toString());
			
			//solamente aca debo amentar la frecuancia del caracter
		descompresorInsertarSimbolo(simboloComprimido);

		if (modeloGlobal < orden) {
			modeloGlobal++;
			aumentoContexto(simbolo);
		} else
			corroContexto(simbolo);

		modificarTamanio(modeloGlobal, simbolo.length());
			
	} while (EOF == false);
		
	byte[] baDes = new byte[descArit.getOut().size()];
	baDes = descArit.getOut().toByteArray();
	
	return baDes;
	
	//String str = new String(baDes,0,baDes.length,"UTF-16BE");
	//System.out.println(str);

 }
	
//	dependiendo del orden actual (aca lo llamo nivelActual)
	private ArchivoDiccionario abrirArchivoModeloActual(int nivelActual)
			throws FileNotFoundException, IOException {
		ArchivoDiccionario archivo = null;
		switch (nivelActual) {
		case 0:
			archivo = new ArchivoDiccionario("sistema/PPMCmodel_0.dat", false);
			break;

		case 1:
			archivo = new ArchivoDiccionario("sistema/PPMCmodel_1.dat", false);
			break;

		case 2:
			archivo = new ArchivoDiccionario("sistema/PPMCmodel_2.dat", false);
			break;

		case 3:
			archivo = new ArchivoDiccionario("sistema/PPMCmodel_3.dat", false);
			break;

		default:
			archivo = new ArchivoDiccionario("sistema/PPMCmodel_4.dat", false);
			break;

		}
		return archivo;

	}
	
//	agrego el contexto al modelo y ademas le agrego el simboloAComprimir
	private void agregoContextoAlModelo(String NuevoContexto, int NewSimboloAComprimir) throws Exception {

		ContextoPPMC PPMCcontextoAAgregar = new ContextoPPMC(NuevoContexto);

		emito(ESC, PPMCcontextoAAgregar.getArrayPosFrecuencia());
		agregoSimboloAlContexto(PPMCcontextoAAgregar.getArrayPosFrecuencia(),
				NewSimboloAComprimir);
		this.listaContextoPPMC.add(PPMCcontextoAAgregar);
	}

	
	private void agregoSimboloAlContexto(ArrayList<RegistroPosicionFrecuencia> lista, int simboloAComprimir2) {
		RegistroPosicionFrecuencia reg = new RegistroPosicionFrecuencia();
		reg.setPosicion(simboloAComprimir2);
		reg.setFrecuencia(1);
		lista.add(reg);
				
	}
	
	private void descompresorAgregoSimboloAlContexto(ContextoPPMC contextoAux, ArrayList<RegistroPosicionFrecuencia> lista, int simboloAComprimir2) {
		RegistroPosicionFrecuencia reg = new RegistroPosicionFrecuencia();
		reg.setPosicion(simboloAComprimir2);
		reg.setFrecuencia(1);
		lista.add(reg);
		contextoAux.aumentarTotal();
		
		if (estaSimboloAComprimir(lista, ESC)==false){
			RegistroPosicionFrecuencia reg2 = new RegistroPosicionFrecuencia();
			reg2.setPosicion(ESC);
			reg2.aumentarFrecuencia();
			lista.add(reg2);
			contextoAux.aumentarTotal();
		} else descompresorAumentarFrecuencia(contextoAux, lista, ESC);
					
		
	}
	
	private void aumentarFrecuencia(ArrayList<RegistroPosicionFrecuencia> listaPosFrec, int simbolo) {

		for (RegistroPosicionFrecuencia reg : listaPosFrec) {
			if (reg.getPosicion() == simbolo)
				reg.aumentarFrecuencia();
		}
	}
	
	private void descompresorAumentarFrecuencia(ContextoPPMC contexto, ArrayList<RegistroPosicionFrecuencia> listaPosFrec, int simbolo) {

		for (RegistroPosicionFrecuencia reg : listaPosFrec) {
			if (reg.getPosicion() == simbolo)
				reg.aumentarFrecuencia();
		}
		
		contexto.aumentarTotal();
	}
	
	
	private void aumentoContexto(String caracter) {
		if (modeloGlobal == 1)
			contextoGlobal = caracter;
		else
			contextoGlobal = contextoGlobal + caracter;
	}
	
//	vaciamos lo q tenga la lista y cargamos la lista con lo q tenga el archivo
	private void cargarListaContextosModeloActual() throws IOException {
		int offset = 0;
		this.listaContextoPPMC.clear();
		while (offset != this.archivoModelo.getOffSetEOF()) {
			ContextoPPMC contextoAux = new ContextoPPMC();
			this.archivoModelo.leerRegistro(contextoAux);
			this.listaContextoPPMC.add(contextoAux);
			offset = (int) this.archivoModelo.getFilePointer();
		}

	}

	private void cierroArhivo(ArchivoDiccionario archivo, int nivelActual)
			throws IOException {
		archivo.Erase();
		for (ContextoPPMC contextoAux : listaContextoPPMC) {
			archivo.escribirRegistro(contextoAux);

		}
		archivo.cerrarArchivo();
	}

	public CompresorAritmetico Salida() {
		return compresArit;
	}
	
	private void descompresorInsertarSimbolo(Integer simboloComprimido) throws IOException {
		int modelo = this.modeloActual;
		this.modeloActual = this.modeloGlobal;
		this.contextoActual = contextoGlobal;
		boolean fin = false;
		
		do {
		
		this.archivoModelo = abrirArchivoModeloActual(this.modeloActual);
		archivoModelo.rwArchivo();
 
		cargarListaContextosModeloActual();
        
		if (modeloActual > 0) {
			for (ContextoPPMC contextoAux : listaContextoPPMC) {
				// los modelos -1 y 0 tienen contextos nulos
				if (contextoAux.getContexto().equals(contextoActual)){
					if (estaSimboloAComprimir(contextoAux.getArrayPosFrecuencia(), simboloComprimido)==false){
											
						descompresorAgregoSimboloAlContexto(contextoAux, contextoAux.getArrayPosFrecuencia(), simboloComprimido);
					}
						else{				
					    //aumentarFrecuencia(contextoAux.getArrayPosFrecuencia(), simboloComprimido);
	                    descompresorAumentarFrecuencia(contextoAux, contextoAux.getArrayPosFrecuencia(), simboloComprimido);				
					}
					break;
				}
			}//fin FOR
		} else {
			ContextoPPMC contextoAux = listaContextoPPMC.get(0);
			if (estaSimboloAComprimir(contextoAux.getArrayPosFrecuencia(), simboloComprimido)==false)
				descompresorAgregoSimboloAlContexto(contextoAux, contextoAux.getArrayPosFrecuencia(), simboloComprimido);
			else{				
			    descompresorAumentarFrecuencia(contextoAux, contextoAux.getArrayPosFrecuencia(), simboloComprimido);
			}
		}
		cierroArhivo(archivoModelo, modeloActual);

		//this.archivoModelo.cerrarArchivo();
		this.modeloActual--;

		if (modeloActual > 0) 
			disminuyoContexto(contextoActual, modeloGlobal- modeloActual);
		
		if (modeloActual == modelo)
			fin = true;
		
		}while(fin == false);
	}
		
		
		
		
	private boolean descomprimoUltimoNivel() throws Exception {

		ArrayList<RegistroSimbolos> ultimaLista = new ArrayList<RegistroSimbolos>(
				65538);
		ArrayList<RegistroSimbolos> listaSimbolos = new ArrayList<RegistroSimbolos>();
		Long contador = 0L;

		listaSimbolos = generarListaDeUnos();
		ultimaLista = aplicarExclusion(listaSimbolos);
		contador = caluloTotal(ultimaLista);

		TablaProbabilidades tabla = new TablaProbabilidades();

		tabla.setATablaProbabilidades(ultimaLista);
		tabla.setTotal(contador);

		simbolosExcluidos.clear();
		return descArit.descomprimirSiguientePaso(tabla);

	}

	private boolean descompresorAgregoContextoAlModelo(String contexto) throws Exception {
		ContextoPPMC contextoAux = new ContextoPPMC(contexto);
	//	contextoAux.aumentarTotal();
		
		this.listaContextoPPMC.add(contextoAux);
		
		ArrayList<RegistroSimbolos> lista = new ArrayList<RegistroSimbolos>();
		lista = generarListaDeCeros();
		RegistroSimbolos rs = new RegistroSimbolos();
		rs.setProbabilidad(1);
		lista.set(65536, rs);
		
		TablaProbabilidades tabla = new TablaProbabilidades();
		tabla.setATablaProbabilidades(lista);
		tabla.setTotal(1);
		
		return descArit.descomprimirSiguientePaso(tabla,true);

	}

	private ArrayList<RegistroSimbolos> generarListaDeCeros() {
		ArrayList<RegistroSimbolos> lista = new ArrayList<RegistroSimbolos>();
		
		lista.clear();
		for (int i = 0; i <= 65537; i++) {
			RegistroSimbolos rs = new RegistroSimbolos();
			rs.setProbabilidad(0);
			lista.add(i, rs);
		}
		return lista;
	}

	private ArrayList<RegistroSimbolos> generarListaDeUnos() {
		ArrayList<RegistroSimbolos> lista = new ArrayList<RegistroSimbolos>();
		
		lista.clear();
		for (int i = 0; i <= 65537; i++) {
			RegistroSimbolos rs = new RegistroSimbolos();
			rs.setProbabilidad(1);
			lista.add(i, rs);
		}
		return lista;
	}

	private boolean descomprimirEnContexto(ContextoPPMC contextoAux, ArrayList<RegistroPosicionFrecuencia> listaPosFrecuencia)throws Exception {
		
		TablaProbabilidades TablaP = new TablaProbabilidades();
		ArrayList<RegistroSimbolos> listaSimbolos = new ArrayList<RegistroSimbolos>();
		long contador = contextoAux.getTotal();
		ArrayList<RegistroSimbolos> ultimaLista = new ArrayList<RegistroSimbolos>();
		
		//if (contador == 0){
		 //contador =1;
		//}
		
		
		if (estaSimboloAComprimir(listaPosFrecuencia, ESC)==false){
			
			ArrayList<RegistroPosicionFrecuencia> listaAux = new ArrayList<RegistroPosicionFrecuencia>();
			RegistroPosicionFrecuencia reg = new RegistroPosicionFrecuencia();
			reg.setPosicion(ESC);
			reg.aumentarFrecuencia();
			listaAux.add(reg);
			listaSimbolos = generarListaRegistroSimblos(listaAux);
			contador = 1;
			ultimaLista = aplicarExclusion(listaSimbolos);
			TablaP.setATablaProbabilidades(ultimaLista);
			TablaP.setTotal(contador);
			return descArit.descomprimirSiguientePaso(TablaP,true);
			
			
		}else{
				listaSimbolos = generarListaRegistroSimblos(listaPosFrecuencia);
				ultimaLista = aplicarExclusion(listaSimbolos);
				TablaP.setATablaProbabilidades(ultimaLista);
				TablaP.setTotal(contador);
				return descArit.descomprimirSiguientePaso(TablaP);
		}
	}
	
	private void corroContexto(String simbolo) {
		int largo = contextoGlobal.length();
		String aux = contextoGlobal.substring(this.tam1, largo);
		aux = aux + simbolo;
		contextoGlobal = aux;

	}

		
	private void disminuyoContexto(String ctxActual, int modelo) {
		int tamanio = 0;
		int largo = 0;
		switch (modelo) {
		case 1:
			tamanio = this.tam1;
			break;
		case 2:
			tamanio = this.tam2;
			//tamanio = this.tam1 + this.tam2;
			break;

		case 3:
			tamanio = this.tam3; //+ this.tam2;
			//tamanio = this.tam1 + this.tam2 + this.tam3;
			break;

		case 4:
			tamanio = this.tam4; //+ this.tam2 + this.tam3;
			//tamanio = this.tam1 + this.tam2 + this.tam3 + this.tam4;
			break;
		}

		largo = ctxActual.length();

		String aux = ctxActual.substring(tamanio, largo);
		this.contextoActual = aux;
	}

	private int comprimirEnContexto(ContextoPPMC contextoAux,
			int simboloAComprimir) throws Exception {
		if (estaSimboloAComprimir(contextoAux.getArrayPosFrecuencia(),
				simboloAComprimir)) {
			emito(simboloAComprimir, contextoAux.getArrayPosFrecuencia());
			simbolosExcluidos.clear();
			return 1;//true;

		} else {
			emito(ESC, contextoAux.getArrayPosFrecuencia());
			cargarListaExclusion(contextoAux.getArrayPosFrecuencia());
			agregoSimboloAlContexto(contextoAux.getArrayPosFrecuencia(),
					simboloAComprimir);
			return 0;//false
		}
	}

	private boolean estaSimboloAComprimir(ArrayList<RegistroPosicionFrecuencia> arrayPosFrecuencia,	int simboloAComprimir) {
		boolean esta = false;
		for (RegistroPosicionFrecuencia reg : arrayPosFrecuencia) {
			if (reg.getPosicion() == simboloAComprimir)
				esta = true;
		}
		return esta;
	}

	private void modificarTamanio(int modelo, int tamanio) {
		switch (modelo) {
		case 1:
			this.tam1 = tamanio;
			break;
		case 2:
			if (tam2 != 0)
				this.tam1 = this.tam2;
			this.tam2 = tamanio;
			break;

		case 3:
			if (tam3 != 0) {
				this.tam1 = this.tam2;
				this.tam2 = this.tam3;
			}

			this.tam3 = tamanio;
			break;

		case 4:
			if (tam4 != 0) {
				this.tam1 = this.tam2;
				this.tam2 = this.tam3;
				this.tam3 = this.tam4;
			}
			this.tam4 = tamanio;
			break;
		}
	}

	private void cargarListaExclusion(
			ArrayList<RegistroPosicionFrecuencia> arraySimbolos) {
		for (int i = 0; i < arraySimbolos.size(); i++) { //estoy omitiendo el ESC y el EOF
			RegistroPosicionFrecuencia rs = new RegistroPosicionFrecuencia();
			rs = arraySimbolos.get(i);
			int pos = rs.getPosicion();
			if ((pos < ESC) && (!this.simbolosExcluidos.contains(pos)))
				this.simbolosExcluidos.add(pos);
		}

	}

	

	private void emitoUltimoNivel(int simbolo) throws Exception {

		ArrayList<RegistroSimbolos> ultimaLista = new ArrayList<RegistroSimbolos>(
				65538);
		ArrayList<RegistroSimbolos> listaSimbolos = new ArrayList<RegistroSimbolos>();
		Long contador = 0L;

		listaSimbolos = generarListaDeUnos();
		ultimaLista = aplicarExclusion(listaSimbolos);
		contador = caluloTotal(ultimaLista);

		//System.out.println("Modelo: " + modeloActual + "\tContexto: " + contextoActual);
		//System.out.println("Simbolo: " + simbolo + "\tFrecuencia: "	+ (float) ultimaLista.get(simbolo).getProbabilidad()/ contador);
		//System.out.println();
		comprimirConArit(ultimaLista, simbolo, contador);
		simbolosExcluidos.clear();
	}

	private void emito(int simbolo,
			ArrayList<RegistroPosicionFrecuencia> listaPosFrec)
			throws Exception {

		ArrayList<RegistroSimbolos> listaSimbolos = new ArrayList<RegistroSimbolos>();
		listaSimbolos = generarListaRegistroSimblos(listaPosFrec);

		ArrayList<RegistroSimbolos> ultimaLista = new ArrayList<RegistroSimbolos>();
		Long contador = 0L;

		if (simbolo != ESC) {
			ultimaLista = aplicarExclusion(listaSimbolos);
			contador = caluloTotal(ultimaLista);
			//System.out.println("Modelo: " + modeloActual + "\tContexto: "	+ contextoActual);
			//System.out.println("Simbolo: " + simbolo + "\tFrecuencia: "			+(float) ultimaLista.get(simbolo).getProbabilidad() / contador);
			//System.out.println();
			comprimirConArit(ultimaLista, simbolo, contador);
			aumentarFrecuencia(listaPosFrec, simbolo);
			//listaPosFrec.get(simbolo).aumentarFrecuencia();
		} else {//el simbolo es el ESC	

			if (estaSimboloAComprimir(listaPosFrec, ESC) == false) {
				RegistroPosicionFrecuencia reg = new RegistroPosicionFrecuencia();
				reg.setPosicion(ESC);
				reg.aumentarFrecuencia();
				listaPosFrec.add(reg);
				//System.out.println("Modelo: " + modeloActual + "\tContexto: "+ contextoActual);
				//System.out.println("Simbolo: " + simbolo + "\tFrecuencia: " + 1);
				//System.out.println();
				
				ArrayList<RegistroSimbolos> lista = new ArrayList<RegistroSimbolos>(65538);
				lista = generarListaDeCeros();
				RegistroSimbolos reg2 = new RegistroSimbolos();
			    reg2.setProbabilidad(1);
				lista.set(65536, reg2);
				comprimirConArit(lista, ESC, (long) 1,true);
				
				
				
			} else {
				ultimaLista = aplicarExclusion(listaSimbolos);
				contador = caluloTotal(ultimaLista);
				//System.out.println("Modelo: " + modeloActual + "\tContexto: "+ contextoActual);
				//System.out.println("Simbolo: " + simbolo + "\tFrecuencia: "	+ (float) ultimaLista.get(simbolo).getProbabilidad()/ contador);
				//System.out.println();
				comprimirConArit(ultimaLista, simbolo, contador);
				aumentarFrecuencia(listaPosFrec, simbolo);

			}
		}
	}

	

	private void comprimirConArit(ArrayList<RegistroSimbolos> lista, int esc, long frecuencia, boolean b) throws Exception {
		TablaProbabilidades tablaP = new TablaProbabilidades();
		tablaP.setATablaProbabilidades(lista);
		tablaP.setTotal(frecuencia);
		this.compresArit.calcularIntervalo(tablaP, esc,b);

	}

	private ArrayList<RegistroSimbolos> generarListaRegistroSimblos(
			ArrayList<RegistroPosicionFrecuencia> listaPosFrec) {
		ArrayList<RegistroSimbolos> lista = new ArrayList<RegistroSimbolos>(
				65538);
		lista = generarListaDeCeros();
		for (int i = 0; i < listaPosFrec.size(); i++) {
			RegistroPosicionFrecuencia rpf = new RegistroPosicionFrecuencia();
			RegistroSimbolos rs = new RegistroSimbolos();
			rpf = listaPosFrec.get(i);
			rs.setProbabilidad(rpf.getFrecuencia());
			lista.set(rpf.getPosicion(), rs);
		}
		return lista;
	}

	private void comprimirConArit(ArrayList<RegistroSimbolos> ultimaLista,
			int simbolo, Long contador) throws Exception {

		TablaProbabilidades tablaP = new TablaProbabilidades();
		tablaP.setATablaProbabilidades(ultimaLista);
		tablaP.setTotal(contador);
		this.compresArit.calcularIntervalo(tablaP, simbolo);

	}

	private Long caluloTotal(ArrayList<RegistroSimbolos> ultimaLista) {
		Long contador = 0L;
		for (int i = 0; i <= 65537; i++) {
			Long proba = ultimaLista.get(i).getProbabilidad();
			contador = contador + proba;

		}

		return contador;
	}

	
	private ArrayList<RegistroSimbolos> aplicarExclusion(
			ArrayList<RegistroSimbolos> listaRegistro) throws Exception {
		ArrayList<RegistroSimbolos> listaAux = new ArrayList<RegistroSimbolos>(
				65538);

		listaAux = generarListaDeCeros();

		for (int i = 0; i <= 65537; i++) {
			//if (!this.simbolosExcluidos.contains(i)) {

				RegistroSimbolos rsAux = new RegistroSimbolos();
				Long proba = listaRegistro.get(i).getProbabilidad();
				rsAux.setProbabilidad(proba);
				listaAux.set(i, rsAux);
			//}
		}

		return listaAux;
	}

	private void crearArchivos(int orden) throws FileNotFoundException,
			IOException {

		//creo el siguiente archivoModelo O con un solo elemento 
		this.archivoModelo = new ArchivoDiccionario("sistema/PPMCmodel_0.dat", true);

		ContextoPPMC contextoAux = new ContextoPPMC("vacio");
	    //contextoAux.aumentarTotal();

		archivoModelo.escribirRegistro(contextoAux);

		this.archivoModelo.cerrarArchivo();

		//ahora hago los otros 2 modelos pero vacios;
		this.archivoModelo = new ArchivoDiccionario("sistema/PPMCmodel_1.dat", true);
		this.archivoModelo.cerrarArchivo();
		this.archivoModelo = new ArchivoDiccionario("sistema/PPMCmodel_2.dat", true);
		this.archivoModelo.cerrarArchivo();

		switch (orden) {
		case 2:
			break;

		case 3:
			this.archivoModelo = new ArchivoDiccionario("sistema/PPMCmodel_3.dat", true);
			this.archivoModelo.cerrarArchivo();
			break;

		case 4:
			this.archivoModelo = new ArchivoDiccionario("sistema/PPMCmodel_3.dat", true);
			this.archivoModelo.cerrarArchivo();

			this.archivoModelo = new ArchivoDiccionario("sistema/PPMCmodel_4.dat", true);
			this.archivoModelo.cerrarArchivo();
			break;
		}
	}

	
}